import { IRouterContext } from "koa-router";
import { oauthApi, api } from "../util/wechat";
import * as redis from "redis";
import * as jwtUtil from "../util/jwt";
import * as config from "config";
import { sql } from "../util/db";
const redisClient: any = redis.createClient();
import { Sex } from "../enum";
import { getOauthUrl } from "../util/wechat";

export const login = async (ctx: IRouterContext) => {
    const code = ctx.query.code;
    const openid = await getOpenidAndSaveUser(code);
    const token = await jwtUtil.genToken({ openid: openid });
    ctx.cookies.set('token', token, {
        httpOnly: true,
        maxAge: 1000 * 3600 * 24, //一天
        overwrite: true
    });
    ctx.cookies.set('openid', openid, {
        httpOnly: false,
        maxAge: 1000 * 3600 * 24, //一天
        overwrite: true
    });
    const state = ctx.query.state;
    ctx.redirect(state);
}

export const check = async (ctx: IRouterContext, next: () => Promise<any>) => {
    const token = ctx.cookies.get('token');
    const jwtResult = await jwtUtil.verify(token);
    if (jwtResult) {
        await next();
    } else {
        ctx.status = 401;
    }
}

export const getWechatQrcodeUrl = async (ctx: IRouterContext) => {
    const o = await api.createTmpQRCode(0, 1800);
    const url = api.showQRCodeURL(o.ticket);
    ctx.body = { url: url };
}

async function getOpenidAndSaveUser(code: string): Promise<string> {
    let openid: string = await redisClient.getAsync('code_' + code);
    if (!openid) {
        const wechatToken = await oauthApi.getAccessToken(code);
        openid = wechatToken.data.openid;
        const { rows } = await sql.query(`select count(1) from t_user where openid=$1`, [openid]);
        const count = rows[0].count;
        if (count == 0) {
            const userInfo = await oauthApi.getUser(openid);
            const text = `insert into t_user(openid, sex, nickname, headimgurl) values($1, $2, $3, $4)`;
            const params = [openid, Sex[userInfo.sex], userInfo.nickname, userInfo.headimgurl];
            await sql.query(text, params);
        }
        await redisClient.setAsync('code_' + code, openid, 'EX', 5 * 60);
    }
    return openid;
}

const fontRootUrl: string = config.get('fontRootUrl');
export const getLoginUrl = async (ctx: IRouterContext) => {
    const url = ctx.query.url;
    const community_id = url.split('=').pop();
    const loginUrl = fontRootUrl + '/api/auth/login';
    const oauthurl = api.getOauthUrl(loginUrl, url, true);
    await sql.query(`update t_community set url=$1 where id=$2`, [oauthurl, community_id]);
    ctx.body = fontRootUrl + `/api/auth/loginFromCommunity/${community_id}`;
}

export const loginFromCommunity = async (ctx: IRouterContext) => {
    const community_id = ctx.params.community_id;
    const { rows } = await sql.query(`select url from t_community where id=$1`, [community_id]);
    const url = rows[0].url;
    ctx.redirect(url);
}